package com.aiapphub.SystemCode.service;

import com.aiapphub.SystemCode.entity.AiFile;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * AI对话文件服务 - 支持 Dify API 文件上传（不再使用本地数据库存储）
 */
@Slf4j
@Service
public class DifyFileService {
    
    private static final String UPLOAD_PATH = "uploads/ai-files/";
    
    @Value("${dify.api.url:https://api.dify.ai/v1}")
    private String difyApiUrl;
    
    @Value("${dify.api.key:}")
    private String difyApiKey;
    
    @Resource
    private UserService userService;
    
    private final OkHttpClient httpClient;
    
    public DifyFileService() {
        this.httpClient = new OkHttpClient.Builder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .build();
    }
    
    /**
     * 上传文件到Dify API
     * @param file 文件
     * @param userId 用户ID
     * @param apiKey 使用的 API Key（如果为 null，则使用默认配置的 apiKey）
     * @return 文件信息
     * @throws IOException 上传异常
     */
    public AiFile uploadFileToDify(MultipartFile file, String userId, String apiKey) throws IOException {
        // 使用用户服务获取用户ID
        String actualUserId = userService.getCurrentUserId();
        
        // 如果传入了 apiKey，使用传入的；否则使用默认配置的
        String actualApiKey = (apiKey != null && !apiKey.trim().isEmpty()) ? apiKey : difyApiKey;
        
        // 检查配置
        if (actualApiKey == null || actualApiKey.trim().isEmpty()) {
            log.error("Dify API密钥未配置");
            throw new RuntimeException("Dify API密钥未配置");
        }
        if (difyApiUrl == null || difyApiUrl.trim().isEmpty()) {
            log.error("Dify API地址未配置");
            throw new RuntimeException("Dify API地址未配置");
        }
        
        // 验证文件类型
        String contentType = file.getContentType();
        if (!isValidFileType(contentType)) {
            throw new RuntimeException("不支持的文件类型: " + contentType + 
                "，仅支持图片格式 (png, jpeg, jpg, webp, gif) 和文档格式 (pdf, doc, docx, xls, xlsx)");
        }
        
        // 验证文件大小 (限制为10MB)
        long maxSize = 10 * 1024 * 1024; // 10MB
        if (file.getSize() > maxSize) {
            throw new RuntimeException("文件大小超过限制，最大支持10MB");
        }
        
        try {
            // 构建请求体
            RequestBody fileBody = RequestBody.create(
                file.getBytes(),
                MediaType.parse(contentType)
            );
            
            MultipartBody requestBody = new MultipartBody.Builder()
                    .setType(MultipartBody.FORM)
                    .addFormDataPart("file", file.getOriginalFilename(), fileBody)
                    .addFormDataPart("user", actualUserId)
                    .build();
            
            // 构建请求
            Request request = new Request.Builder()
                    .url(difyApiUrl + "/files/upload")
                    .post(requestBody)
                    .addHeader("Authorization", "Bearer " + actualApiKey)
                    .build();
            
            log.info("开始上传文件到Dify API: {} ({}), 用户: {}", file.getOriginalFilename(), getFileTypeFriendlyName(contentType), actualUserId);
            
            // 执行请求
            try (Response response = httpClient.newCall(request).execute()) {
                if (response.isSuccessful()) {
                    String responseBody = response.body() != null ? response.body().string() : "";
                    log.info("Dify API上传成功: {}", responseBody);
                    
                    // 解析响应并保存到本地数据库
                    return saveFileInfoFromDifyResponse(file, actualUserId, responseBody);
                } else {
                    String errorBody = response.body() != null ? response.body().string() : "Unknown error";
                    log.error("Dify API上传失败，状态码: {}, 错误信息: {}", response.code(), errorBody);
                    String errorMessage;
                    if (response.code() == 401) {
                        errorMessage = "API认证失败，请检查Dify API密钥配置";
                    } else if (response.code() == 403) {
                        errorMessage = "API访问被拒绝，请检查权限配置";
                    } else if (response.code() == 413) {
                        errorMessage = "文件大小超过限制";
                    } else if (response.code() >= 500) {
                        errorMessage = "Dify服务器内部错误，请稍后重试";
                    } else {
                        errorMessage = "上传失败: " + errorBody;
                    }
                    throw new RuntimeException(errorMessage);
                }
            }
        } catch (IOException e) {
            log.error("上传文件到Dify API网络异常", e);
            if (e.getMessage().contains("timeout")) {
                throw new RuntimeException("请求超时，请检查网络连接", e);
            } else {
                throw new RuntimeException("网络连接失败: " + e.getMessage(), e);
            }
        }
    }
    
    /**
     * 验证是否为支持的文件类型（图片 + 文档）
     */
    private boolean isValidFileType(String contentType) {
        if (contentType == null) return false;
        
        // 图片格式
        boolean isImage = contentType.equals("image/png") ||
                         contentType.equals("image/jpeg") ||
                         contentType.equals("image/jpg") ||
                         contentType.equals("image/webp") ||
                         contentType.equals("image/gif");
        
        // 文档格式
        boolean isDocument = contentType.equals("application/pdf") ||
                            contentType.equals("application/msword") ||
                            contentType.equals("application/vnd.openxmlformats-officedocument.wordprocessingml.document") ||
                            contentType.equals("application/vnd.ms-excel") ||
                            contentType.equals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        
        return isImage || isDocument;
    }
    
    /**
     * 验证是否为支持的图片类型（保持向后兼容）
     */
    private boolean isValidImageType(String contentType) {
        if (contentType == null) return false;
        return contentType.equals("image/png") ||
               contentType.equals("image/jpeg") ||
               contentType.equals("image/jpg") ||
               contentType.equals("image/webp") ||
               contentType.equals("image/gif");
    }
    
    /**
     * 从Dify响应中解析文件信息并创建文件信息对象（不保存到本地数据库）
     */
    private AiFile saveFileInfoFromDifyResponse(MultipartFile file, String userId, String responseBody) {
        try {
            // 解析 Dify API 响应，提取文件信息
            log.info("原始 Dify API 响应: {}", responseBody);
            
            // 解析 JSON 响应以提取文件 ID
            JSONObject difyResponse = null;
            String difyFileId = null;
            
            try {
                difyResponse = JSON.parseObject(responseBody);
                // Dify API 通常返回格式：{"id": "file-xxx", "name": "...", "type": "..."}
                difyFileId = difyResponse.getString("id");
                
                if (difyFileId == null || difyFileId.trim().isEmpty()) {
                    // 尝试其他可能的字段名
                    difyFileId = difyResponse.getString("file_id");
                    if (difyFileId == null || difyFileId.trim().isEmpty()) {
                        difyFileId = difyResponse.getString("upload_file_id");
                    }
                }
                
                log.info("提取到的 Dify 文件 ID: {}", difyFileId);
            } catch (Exception jsonError) {
                log.warn("解析 Dify API 响应 JSON 失败: {}, 错误: {}", responseBody, jsonError.getMessage());
            }
            
            // 创建 AiFile 对象
            AiFile aiFile = new AiFile();
            
            // 生成一个临时的数字 ID（因为我们不再使用数据库）
            aiFile.setId(System.currentTimeMillis());
            
            aiFile.setFileName(file.getOriginalFilename());
            aiFile.setOriginalName(file.getOriginalFilename());
            aiFile.setFilePath("dify://" + (difyFileId != null ? difyFileId : file.getOriginalFilename()));
            aiFile.setFileSize(file.getSize());
            aiFile.setFileType(file.getContentType());
            aiFile.setFileExtension(getFileExtension(file.getOriginalFilename()));
            aiFile.setUserId(userId);
            aiFile.setUploadTime(LocalDateTime.now());
            aiFile.setStatus("SUCCESS");
            
            // 如果成功解析了 Dify 响应，则增强响应数据以便前端处理
            if (difyResponse != null && difyFileId != null) {
                // 确保响应中包含标准化的文件 ID 字段，方便前端提取
                difyResponse.put("upload_file_id", difyFileId);
                difyResponse.put("file_id", difyFileId);
                difyResponse.put("id", difyFileId);
                aiFile.setDifyResponse(difyResponse.toJSONString());
                // 直接设置 uploadFileId 字段，方便前端直接获取
                aiFile.setUploadFileId(difyFileId);
            } else {
                aiFile.setDifyResponse(responseBody); // 保存原始响应
            }
            
            log.info("文件已成功上传到 Dify: {}, Dify文件ID: {}, 大小: {} bytes", 
                     file.getOriginalFilename(), difyFileId, file.getSize());
            return aiFile;
            
        } catch (Exception e) {
            log.error("解析文件信息失败", e);
            throw new RuntimeException("解析文件信息失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 获取文件类型的友好名称
     */
    private String getFileTypeFriendlyName(String contentType) {
        if (contentType == null) return "未知";
        
        switch (contentType) {
            case "image/png":
                return "PNG图片";
            case "image/jpeg":
            case "image/jpg":
                return "JPEG图片";
            case "image/webp":
                return "WebP图片";
            case "image/gif":
                return "GIF图片";
            case "application/pdf":
                return "PDF文档";
            case "application/msword":
                return "Word文档";
            case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
                return "Word文档";
            case "application/vnd.ms-excel":
                return "Excel表格";
            case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
                return "Excel表格";
            default:
                return contentType;
        }
    }
    
    /**
     * 获取文件扩展名
     */
    private String getFileExtension(String filename) {
        if (filename != null && filename.contains(".")) {
            return filename.substring(filename.lastIndexOf("."));
        }
        return "";
    }
    
    /**
     * 上传文件（本地存储，已弃用）
     * @deprecated 已弃用，改为使用 uploadFileToDify 方法直接上传到 Dify
     */
    @Deprecated
    public AiFile uploadFile(MultipartFile file, String userId) throws IOException {
        throw new UnsupportedOperationException("本地文件存储已弃用，请使用 uploadFileToDify 方法");
    }
    
    /**
     * 根据用户ID获取文件列表（已弃用）
     * @deprecated 已弃用，文件信息不再存储在本地数据库
     */
    @Deprecated
    public List<AiFile> getFilesByUserId(String userId) {
        throw new UnsupportedOperationException("文件信息不再存储在本地数据库");
    }
    
    /**
     * 根据ID获取文件（已弃用）
     * @deprecated 已弃用，文件信息不再存储在本地数据库
     */
    @Deprecated
    public AiFile getFileById(Long fileId) {
        throw new UnsupportedOperationException("文件信息不再存储在本地数据库");
    }
    
    /**
     * 删除文件（已弃用）
     * @deprecated 已弃用，文件信息不再存储在本地数据库
     */
    @Deprecated
    public boolean deleteFile(Long fileId) {
        throw new UnsupportedOperationException("文件信息不再存储在本地数据库");
    }
}
